
//初始化标尺
import {boxMoveXy, drawData, rulerLines, showScale} from "./pageData";
import {reactive} from "vue";

export interface RulerLine {
    key: string;
    type: string;
    v: number;
    move: number,
    showTip: boolean,
    isRetain: boolean
}

class Ruler{
    canvasX : HTMLCanvasElement;
    canvasY : HTMLCanvasElement;

    ctxX : CanvasRenderingContext2D;
    ctxY : CanvasRenderingContext2D;

    editElement: HTMLElement;
    rulerElement: HTMLElement;
    rulerXElement: HTMLElement;
    rulerYElement: HTMLElement;

    lineIdGenerate = 0;
    leftClick:boolean = false;


    constructor() {
        this.rulerElement = document.querySelector('.ruler-wrapper');
        this.rulerXElement = document.querySelector('.ruler-wrapper .ruler-x');
        this.rulerYElement = document.querySelector('.ruler-wrapper .ruler-y');
        this.editElement = document.querySelector('.edit-content-component');

        //初始化画布
        this.canvasX = document.createElement('canvas');
        this.canvasY = document.createElement('canvas');

        this.rulerXElement.append(this.canvasX);
        this.rulerYElement.append(this.canvasY);

        this.ctxX = this.canvasX.getContext('2d');
        this.ctxY = this.canvasY.getContext('2d');

        this.updateRuler();
        this.onRulerLine();
    }

    updateRuler(){
        let editElementRect = this.editElement.getBoundingClientRect();
        this.updateRulerX(editElementRect);
        this.updateRulerY(editElementRect);


    }

    updateRulerX(editElementRect: DOMRect){
        this.canvasX.width = editElementRect.width;
        this.canvasX.height = 15;

        this.ctxX.textBaseline = "top";
        this.ctxX.font = "14px Arial";
        this.ctxX.strokeStyle = "#abb0b7";
        this.ctxX.fillStyle = "#abb0b7";
        const startX = boxMoveXy.value.x;
        this.ctxX.fillText("0",startX + 2,0,this.canvasX.width);
        this.ctxX.lineWidth = 1;
        this.ctxX.moveTo(startX,0);
        this.ctxX.lineTo(startX,this.canvasX.height);

        this.ctxX.moveTo(startX,this.canvasX.height);
        this.ctxX.lineTo(startX + drawData.value.width * showScale.value / 100,this.canvasX.height);
        this.ctxX.stroke();

        //实际宽度 50像素一个标度
        const diffs = [20,50,100,200,400,800];
        const showDiffNum =  drawData.value.width * showScale.value / 100 / 50;

        let diff = 100;
        if(showDiffNum <= 1){
            diff = diffs[diffs.length];
        }else if(showDiffNum <= 2){
            diff = diffs[diffs.length - 1];
        }else if(showDiffNum <= 4){
            diff = diffs[diffs.length - 2];
        }else if (showDiffNum <= 8){
            diff = diffs[diffs.length - 3];
        }else if( showDiffNum <= 16){
            diff = diffs[diffs.length - 4];
        }else if(showDiffNum <= 32){
            diff = diffs[diffs.length - 5];
        }else{
            diff = diffs[diffs.length - 6];
        }

        const kds = drawData.value.width / diff;
        for (let i = 1; i < kds; i++) {
            this.ctxX.beginPath();
            this.ctxX.moveTo(startX + i*diff/100*showScale.value,10);
            this.ctxX.lineTo(startX + i*diff/100*showScale.value,this.canvasX.height);
            this.ctxX.stroke();
            this.ctxX.font = "10px Arial";
            this.ctxX.textAlign = "center";
            this.ctxX.fillText(Math.ceil(i*diff) +'',startX + i*diff/100*showScale.value,0,this.canvasX.width);
        }

        this.ctxX.moveTo(startX + drawData.value.width * showScale.value / 100,0);
        this.ctxX.lineTo(startX + drawData.value.width * showScale.value / 100,this.canvasX.height);
        this.ctxX.stroke();
        this.ctxX.textAlign = "left";
        this.ctxX.fillText( drawData.value.width +'',startX + drawData.value.width * showScale.value / 100 + 2,0,this.canvasX.width);
    }

    updateRulerY(editElementRect: DOMRect){
        const _fillText = (text, x, y, maxWidth,height)=>{
            this.ctxY.save();
            let textMetrics = this.ctxY.measureText(text);
            const [left,top] = [x, y];
            const angle = -90;
            this.ctxY.translate(left + textMetrics.width  / 2, top + height / 2);
            this.ctxY.rotate(angle * Math.PI / 180);
            this.ctxY.translate(-(left + textMetrics.width / 2), -(top + height / 2));
            this.ctxY.fillText(text,left,top,maxWidth);
            this.ctxY.restore();
        }

        this.canvasY.width = 15                  ;
        this.canvasY.height = editElementRect.height;

        this.ctxY.textBaseline = "top";
        this.ctxY.font = "14px Arial";
        this.ctxY.strokeStyle = "#abb0b7";
        this.ctxY.fillStyle = "#abb0b7";
        const startY = boxMoveXy.value.y;

        const [left,top] = [0 + 2,startY];
        _fillText("0",left,top,this.canvasY.height,14);



        this.ctxY.lineWidth = 1;
        this.ctxY.moveTo(0,startY);
        this.ctxY.lineTo(this.canvasY.width,startY);

        this.ctxY.moveTo(this.canvasY.width,startY);
        this.ctxY.lineTo(this.canvasY.width,startY + drawData.value.height * showScale.value / 100);
        this.ctxY.stroke();

        //实际宽度 50像素一个标度
        const diffs = [20,50,100,200,400,800];
        const showDiffNum =  drawData.value.height * showScale.value / 100 / 50;

        let diff = 100;
        if(showDiffNum <= 1){
            diff = diffs[diffs.length];
        }else if(showDiffNum <= 2){
            diff = diffs[diffs.length - 1];
        }else if(showDiffNum <= 4){
            diff = diffs[diffs.length - 2];
        }else if (showDiffNum <= 8){
            diff = diffs[diffs.length - 3];
        }else if( showDiffNum <= 16){
            diff = diffs[diffs.length - 4];
        }else if(showDiffNum <= 32){
            diff = diffs[diffs.length - 5];
        }else{
            diff = diffs[diffs.length - 6];
        }

        const kds = drawData.value.height / diff;
        for (let i = 1; i < kds; i++) {
            this.ctxY.beginPath();
            this.ctxY.moveTo(10,startY + i*diff/100*showScale.value);
            this.ctxY.lineTo(this.canvasY.width,startY + i*diff/100*showScale.value);
            this.ctxY.stroke();

            this.ctxY.font = "10px Arial";
            this.ctxY.textBaseline = "top";
            // this.ctxY.fillText(Math.ceil(i*diff) +'',10,startY + i*diff/100*showScale.value,this.canvasY.height);

            this.ctxY.save();
            const text = Math.ceil(i*diff) +'';
            let textMetrics = this.ctxY.measureText(text);
            const [left,top] = [6 - textMetrics.width/2, startY + i*diff/100*showScale.value - 10/2];
            const angle = -90;
            this.ctxY.translate(left + textMetrics.width  / 2, top + 10 / 2);
            this.ctxY.rotate(angle * Math.PI / 180);
            this.ctxY.translate(-(left + textMetrics.width / 2), -(top + 10 / 2));
            this.ctxY.fillText(text,left,top,this.canvasY.height);
            this.ctxY.restore();
            //
            // _fillText(Math.ceil(i*diff) +'',0 -2,startY + i*diff/100*showScale.value - 15,this.canvasY.height,10);
        }

        this.ctxY.moveTo(0,startY + drawData.value.height * showScale.value / 100);
        this.ctxY.lineTo(this.canvasY.width,startY + drawData.value.height * showScale.value / 100);
        this.ctxY.stroke();
        this.ctxY.textAlign = "left";
        // this.ctxY.fillText( drawData.value.height +'',0,startY + drawData.value.height * showScale.value / 100 + 2,this.canvasY.height);
        _fillText(drawData.value.height +'',0 - 2,startY + drawData.value.height * showScale.value / 100 + 6,this.canvasY.height,10);
    }


    onRulerLine(){
        //标线监听 显示
        this.rulerXElement.addEventListener("mousedown",(e:MouseEvent)=>{
            const rect = this.rulerXElement.getBoundingClientRect();
            this.leftClick = true;
            const line = reactive<RulerLine>({key:`line${this.lineIdGenerate++}`,type:'x',v:e.clientY - rect.top - boxMoveXy.value.y,move:e.clientX - rect.left,isRetain:false,showTip:true});

            rulerLines.value.push(line);
            line.isRetain = !(line.v < 0 || line.v > drawData.value.height);

            const mousemove = (e:MouseEvent)=>{
                //转换到画布
                line.v = e.clientY - rect.top - boxMoveXy.value.y;
                line.v = line.v * 100/showScale.value;
                line.v = Math.round(line.v);
                line.move = e.clientX - rect.left;
                line.isRetain = !(line.v < 0 || line.v > drawData.value.height);
            }

            window.addEventListener('mousemove',mousemove)

            const mouseup = ()=>{
                if(line.v < 0 || line.v > drawData.value.height){
                    rulerLines.value.splice(rulerLines.value.indexOf(line),1);
                }
                this.leftClick = false;
                window.removeEventListener('mousemove',mousemove)
                window.removeEventListener('mouseup',mouseup)
            }
            window.addEventListener('mouseup',mouseup)

        })

        this.rulerYElement.addEventListener("mousedown",(e:MouseEvent)=>{
            const rect = this.rulerXElement.getBoundingClientRect();
            this.leftClick = true;
            const line = reactive<RulerLine>({key:`line${this.lineIdGenerate++}`,type:'y',v:e.clientX  - rect.left- boxMoveXy.value.x,move:e.clientY - rect.top,isRetain:false,showTip:true});

            rulerLines.value.push(line);
            line.isRetain = !(line.v < 0 || line.v > drawData.value.height);
            const mousemove = (e:MouseEvent)=>{
                //转换到画布
                line.v = e.clientX - rect.left - boxMoveXy.value.x;
                line.v = line.v * 100/showScale.value;
                line.v = Math.round(line.v);
                line.move = e.clientY - rect.top;
                line.isRetain = !(line.v < 0 || line.v > drawData.value.width);
            }

            window.addEventListener('mousemove',mousemove)

            const mouseup = ()=>{
                if(line.v < 0 || line.v > drawData.value.width){
                    rulerLines.value.splice(rulerLines.value.indexOf(line),1);
                }
                this.leftClick = false;
                window.removeEventListener('mousemove',mousemove)
                window.removeEventListener('mouseup',mouseup)
            }
            window.addEventListener('mouseup',mouseup)

        })
    }

    lineMousedown(e:MouseEvent,line:RulerLine){
        this.leftClick = true;
        const rect = this.rulerXElement.getBoundingClientRect();
        if(line.type === 'x'){
            line.isRetain = !(line.v < 0 || line.v > drawData.value.height);
            const mousemove = (e:MouseEvent)=>{
                //转换到画布
                line.v = e.clientY - rect.top - boxMoveXy.value.y;
                line.v = line.v * 100/showScale.value;
                line.v = Math.round(line.v);
                line.isRetain = !(line.v < 0 || line.v > drawData.value.height);
            }

            window.addEventListener('mousemove',mousemove)

            const mouseup = ()=>{
                if(line.v < 0 || line.v > drawData.value.height){
                    rulerLines.value.splice(rulerLines.value.indexOf(line),1);
                }
                this.leftClick = false;
                window.removeEventListener('mousemove',mousemove)
                window.removeEventListener('mouseup',mouseup)
            }
            window.addEventListener('mouseup',mouseup)
        }else{
            line.isRetain = !(line.v < 0 || line.v > drawData.value.width);
            const mousemove = (e:MouseEvent)=>{
                //转换到画布
                line.v = e.clientX - rect.left - boxMoveXy.value.x;
                line.v = line.v * 100/showScale.value;
                line.v = Math.round(line.v);
                line.isRetain = !(line.v < 0 || line.v > drawData.value.width);
            }

            window.addEventListener('mousemove',mousemove)

            const mouseup = ()=>{
                if(line.v < 0 || line.v > drawData.value.width){
                    rulerLines.value.splice(rulerLines.value.indexOf(line),1);
                }
                this.leftClick = false;
                window.removeEventListener('mousemove',mousemove)
                window.removeEventListener('mouseup',mouseup)
            }
            window.addEventListener('mouseup',mouseup)
        }

    }

    lineMouseOver(e:MouseEvent,line:RulerLine){
        if(line.type === 'x'){
            line.showTip = true;
            line.move = e.clientX - this.rulerXElement.getBoundingClientRect().left;
        }else{
            line.showTip = true;
            line.move = e.clientY - this.rulerXElement.getBoundingClientRect().top;
        }
    }

}

export default Ruler
